
`include "common_header.verilog"

//  *************************************************************************
//  File : pause_xoffpin_xsync
//  *************************************************************************
//  This program is controlled by a written license agreement.
//  Unauthorized Reproduction or Use is Expressly Prohibited. 
//  Copyright (c) 2010 MoreThanIP.com, Germany
//  Designed by : Daniel Koehler
//  info@morethanip.com
//  *************************************************************************
//  Description: Synchronize tx_pfc_xoff control pins into line clock domain.
//               Depending on Mode, class0 indication is used in link
//               pause only and RX FIFO section empty can be used for
//               automatic pause generation.
//  Version    : $Id: pause_xoffpin_xsync.v,v 1.3 2017/04/10 08:23:13 gc Exp $
//  *************************************************************************
module pause_xoffpin_xsync (

   reset_tx_clk,
   tx_clk,
   tx_pfc_xoff,
   xoff_gen,
   rx_septy,
   enable_tx,
   pfc_mode);

parameter PFC_PRIORITIES = 8;   // Number of priorities to support

input   reset_tx_clk;           //  Asynchronous Reset - tx_clk Domain
input   tx_clk;                 //  TX line clock
output   [PFC_PRIORITIES-1:0] tx_pfc_xoff;     //  Transmit Flow Control Generate to MAC in tx clock domain
input   [PFC_PRIORITIES-1:0] xoff_gen;         //  toplevel pins, Transmit Flow Control Generate request inputs (async or ff_tx_clk)
input   rx_septy;               //  RX FIFO section empty (rx_clk)
input   enable_tx;              //  MAC tx enable from host (reg_clk)
input   pfc_mode;               //  PFC enable from host (reg_clk)

wire    [PFC_PRIORITIES-1:0] tx_pfc_xoff; 

wire    [PFC_PRIORITIES-1:0] xoff_gen_t;       //  toplevel pins, Transmit Flow Control Generate request inputs (async or ff_tx_clk)
wire    rx_septy_t;             //  RX FIFO section empty (rx_clk)
wire    enable_tx_t;            //  MAC tx enable from host (reg_clk)
wire    pfc_mode_t;             //  PFC enable from host (reg_clk)
reg     enable_masked;          //  after-reset protection
reg     xoff0_gen_int;          //  class0 pause request

//  get all async input signals into tx clock domain
//  ------------------------------------------------

mtip_xsync #(3+PFC_PRIORITIES) U_ISYNC (
          .data_in({pfc_mode, enable_tx, rx_septy, xoff_gen}),
          .reset(reset_tx_clk),
          .clk(tx_clk),
          .data_s({pfc_mode_t, enable_tx_t, rx_septy_t, xoff_gen_t}));

//  -----------------------------------------
//  control the class0 pin depending on mode.
//  In Link pause mode it is OR'ed with congestion from RX FIFO if it indicates SEPTY=0.
//  -----------------------------------------

always @(posedge reset_tx_clk or posedge tx_clk)
   begin : p0
   if (reset_tx_clk == 1'b 1)
      begin
      enable_masked <= 1'b 0;	
      xoff0_gen_int <= 1'b 0;	
      end
   else
      begin

        //  Mask the enable after reset until rx_septy was at least once at a high level after 
        //  MAC was enabled.

      if (enable_tx_t == 1'b 1 & rx_septy_t == 1'b 1)
         begin
         enable_masked <= 1'b 1;	
         end
      else if (enable_tx_t == 1'b 0 )
         begin
         enable_masked <= 1'b 0;	
         end

        //  control the class0 congestion request depending on mode

      if (enable_masked == 1'b 1 & pfc_mode_t == 1'b 0 & (xoff_gen_t[0] == 1'b 1 | rx_septy_t == 1'b 0))
         begin
        //  link pause: from pin, or auto generate from FIFO section empty threshold
         xoff0_gen_int <= 1'b 1;	
         end
      else if (pfc_mode_t == 1'b 1 )
         begin
        //  PFC mode: only controlled by pin
         xoff0_gen_int <= xoff_gen_t[0];	
         end
      else
         begin
         xoff0_gen_int <= 1'b 0;	
         end

      end
   end

//  ------------------------------------
//  control to MAC, all in tx_clk domain
//  ------------------------------------
assign tx_pfc_xoff = {xoff_gen_t[PFC_PRIORITIES-1:1], xoff0_gen_int}; 

endmodule // module pause_xoffpin_xsync
